package com.uduemc.biso.node.module.controller;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.validation.Valid;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Pageable;
import org.springframework.data.web.PageableDefault;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.uduemc.biso.core.extities.center.custom.statistics.NodeTemplate;
import com.uduemc.biso.core.extities.center.custom.statistics.NodeTemplateRank;
import com.uduemc.biso.core.utils.RestResult;
import com.uduemc.biso.node.core.entities.SConfig;
import com.uduemc.biso.node.module.service.SConfigService;

@RestController
@RequestMapping("/s-config")
public class SConfigController {

	private static final Logger logger = LoggerFactory.getLogger(SConfigController.class);

	@Autowired
	private SConfigService sConfigServiceImpl;

	@PostMapping("/insert")
	public RestResult insert(@Valid @RequestBody SConfig sConfig, BindingResult errors) {
		logger.info("insert: " + sConfig.toString());
		if (errors.hasErrors()) {
			Map<String, Object> message = new HashMap<>();
			for (FieldError fieldError : errors.getFieldErrors()) {
				String field = fieldError.getField();
				String defaultMessage = fieldError.getDefaultMessage();
				message.put(field, defaultMessage);
			}

			return RestResult.error(message);
		}
		SConfig data = sConfigServiceImpl.insert(sConfig);
		return RestResult.ok(data, SConfig.class.toString());
	}

	@PutMapping("/update-by-id")
	public RestResult updateById(@Valid @RequestBody SConfig sConfig, BindingResult errors) {
		logger.info("updateById: " + sConfig.toString());
		if (errors.hasErrors()) {
			Map<String, Object> message = new HashMap<>();
			for (FieldError fieldError : errors.getFieldErrors()) {
				String field = fieldError.getField();
				String defaultMessage = fieldError.getDefaultMessage();
				message.put(field, defaultMessage);
			}

			return RestResult.error(message);
		}
		SConfig findOne = sConfigServiceImpl.findOne(sConfig.getId());
		if (findOne == null) {
			return RestResult.noData();
		}
		SConfig data = sConfigServiceImpl.updateById(sConfig);
		return RestResult.ok(data, SConfig.class.toString());
	}

	@PutMapping("/update-all-by-id")
	public RestResult updateAllById(@Valid @RequestBody SConfig sConfig, BindingResult errors) {
		logger.info("updateById: " + sConfig.toString());
		if (errors.hasErrors()) {
			Map<String, Object> message = new HashMap<>();
			for (FieldError fieldError : errors.getFieldErrors()) {
				String field = fieldError.getField();
				String defaultMessage = fieldError.getDefaultMessage();
				message.put(field, defaultMessage);
			}

			return RestResult.error(message);
		}
		SConfig findOne = sConfigServiceImpl.findOne(sConfig.getId());
		if (findOne == null) {
			return RestResult.noData();
		}
		SConfig data = sConfigServiceImpl.updateAllById(sConfig);
		return RestResult.ok(data, SConfig.class.toString());
	}

	@GetMapping("/find-one/{id:\\d+}")
	public RestResult findOne(@PathVariable("id") Long id) {
		SConfig data = sConfigServiceImpl.findOne(id);
		if (data == null) {
			return RestResult.noData();
		}
		return RestResult.ok(data, SConfig.class.toString());
	}

	@GetMapping(value = { "/find-all" })
	public RestResult findAll(@PageableDefault(page = 0, size = 12) Pageable pageable) {
		logger.info("pageable: " + pageable.toString());
		List<SConfig> findAll = sConfigServiceImpl.findAll(pageable);
		return RestResult.ok(findAll, SConfig.class.toString(), true);
	}

	@GetMapping("/delete-by-id/{id:\\d+}")
	public RestResult deleteById(@PathVariable("id") Long id) {
		SConfig findOne = sConfigServiceImpl.findOne(id);
		if (findOne == null) {
			return RestResult.ok();
		}
		sConfigServiceImpl.deleteById(id);
		return RestResult.ok(findOne);
	}

	@GetMapping("/find-by-host-site-id/{hostId:\\d+}/{siteId:\\d+}")
	public RestResult findByHostSiteId(@PathVariable("hostId") Long hostId, @PathVariable("siteId") Long siteId) {
		SConfig sConfig = sConfigServiceImpl.findInfoByHostSiteId(hostId, siteId);
		return RestResult.ok(sConfig, SConfig.class.toString());
	}

	@GetMapping("/find-by-host-id/{hostId:\\d+}")
	public RestResult findByHostId(@PathVariable("hostId") long hostId) {
		List<SConfig> data = sConfigServiceImpl.findByHostId(hostId);
		if (data == null) {
			return RestResult.noData();
		}
		return RestResult.ok(data, SConfig.class.toString(), true);
	}

	@GetMapping("/find-ok-by-host-id/{hostId:\\d+}")
	public RestResult findOKByHostId(@PathVariable("hostId") long hostId) {
		List<SConfig> data = sConfigServiceImpl.findOKByHostId(hostId);
		if (data == null) {
			return RestResult.noData();
		}
		return RestResult.ok(data, SConfig.class.toString(), true);
	}

	/**
	 * 修改默认站点
	 * 
	 * @param hostId
	 * @param mainSiteId
	 * @return
	 */
	@GetMapping("/change-main-site-by-host-Id/{hostId:\\d+}/{mainSiteId:\\d+}")
	public RestResult changeMainSiteByHostId(@PathVariable("hostId") long hostId, @PathVariable("mainSiteId") long mainSiteId) {
		boolean changeMainSiteByHostId = sConfigServiceImpl.changeMainSiteByHostId(hostId, mainSiteId);
		if (changeMainSiteByHostId) {
			return RestResult.ok(changeMainSiteByHostId, Boolean.class.toString());
		}
		return RestResult.ok(false, Boolean.class.toString());
	}

	/**
	 * 统计模板使用排行数据 从多到少
	 * 
	 * @param trial       是否试用 -1:不区分 0:试用 1:正式
	 * @param review      制作审核 -1:不区分 0-未审核 1-审核通过 2-审核不通过
	 * @param templateAll 是否全部的模板，包含 templateId=0 的部分， 0-否 1-是
	 * @param orderBy     排序 0-asc 1-desc
	 * @param count       统计数量 排行前多少
	 */
	@GetMapping("/query-template-rank/{trial:-?\\d+}/{review:-?\\d+}/{templateAll:\\d+}/{orderBy:\\d+}/{count:\\d+}")
	public RestResult queryTemplateRank(@PathVariable("trial") int trial, @PathVariable("review") int review, @PathVariable("templateAll") int templateAll,
			@PathVariable("orderBy") int orderBy, @PathVariable("count") int count) {
		NodeTemplateRank queryTemplateRank = sConfigServiceImpl.queryTemplateRank(trial, review, templateAll, orderBy, count);
		return RestResult.ok(queryTemplateRank, NodeTemplateRank.class.toString());
	}

	/**
	 * 主要通过 templateIdString 获取模板使用统计，同时顺序不能改变
	 * 
	 * @param trial            是否试用 -1:不区分 0:试用 1:正式
	 * @param review           制作审核 -1:不区分 0-未审核 1-审核通过 2-审核不通过
	 * @param templateIdString 多个 templateId 的字符串
	 */
	@GetMapping("/query-template-rank-by-trial-review-templateIds/{trial:-?\\d+}/{review:-?\\d+}/{templateIdsString}")
	public RestResult queryTemplateByTrialReviewTemplateIds(@PathVariable("trial") int trial, @PathVariable("review") int review,
			@PathVariable("templateIdsString") String templateIdsString) {
		NodeTemplateRank queryTemplate = sConfigServiceImpl.queryTemplateByTrialReviewTemplateIds(trial, review, templateIdsString);
		return RestResult.ok(queryTemplate, NodeTemplate.class.toString());
	}

	/**
	 * 单个模板使用统计
	 * 
	 * @param trial      是否试用 -1:不区分 0:试用 1:正式
	 * @param review     制作审核 -1:不区分 0-未审核 1-审核通过 2-审核不通过
	 * @param templateId 模板ID
	 */
	@GetMapping("/query-template/{trial:-?\\d+}/{review:-?\\d+}/{templateId:\\d+}")
	public RestResult queryTemplate(@PathVariable("trial") int trial, @PathVariable("review") int review, @PathVariable("templateId") long templateId) {
		NodeTemplate queryTemplate = sConfigServiceImpl.queryTemplate(trial, review, templateId);
		return RestResult.ok(queryTemplate, NodeTemplate.class.toString());
	}

	/**
	 * 移动端底部菜单使用数量统计
	 * 
	 * @param trial  是否试用 -1:不区分 0:试用 1:正式
	 * @param review 制作审核 -1:不区分 0-未审核 1-审核通过 2-审核不通过
	 */
	@GetMapping("/query-foot-menu-count/{trial:-?\\d+}/{review:-?\\d+}")
	public RestResult queryFootMenuCount(@PathVariable("trial") int trial, @PathVariable("review") int review) {
		Integer count = sConfigServiceImpl.queryFootMenuCount(trial, review);
		return RestResult.ok(count, Integer.class.toString());
	}
}
